package bad;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class EventLoop {

    public static void main(String[] args) throws InterruptedException {
        ReentrantLock id = new ReentrantLock();
        Condition condition = id.newCondition();
        Vector<Req> reqs = new Vector<>();
        AtomicInteger count = new AtomicInteger();

        new Thread(()->{
            int l = 0;
            while (true){
                try {
                    SomeTopic.debug("开始发送请求");
                    Thread.sleep(1000);
                    Req req = new Req();
                    req.isDone=false;
                    reqs.add(req);
                    SomeTopic.debug("开始发送请求");
                    SomeTopic.debug(reqs);
                    Thread.sleep(1000);
                    req.resBody="this is response";
                    if ((l++)%4!=0)req.isDone=true;
                    count.getAndIncrement();
                    SomeTopic.debug(reqs);
                    SomeTopic.debug("接收到回复，开始通知处理");
                    id.lock();
                    try{
                        condition.signal();
                    }finally {
                        id.unlock();
                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"client").start();
        int k = 0;
        while (true){
            count.set(0);
            SomeTopic.debug("开始一轮询问");
//           Thread.sleep(2000);
            id.lock();
            try {
                while (count.get()==0){
                    SomeTopic.debug("准备贡献出ＣＰＵ，期待一个回复");
                    condition.await();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                id.unlock();
            }
            if ((k++)%2==0) {Thread.sleep(8000);
            SomeTopic.debug("8秒前被唤醒，模拟请求批量回复");}
            SomeTopic.debug("开始一轮调用");
            Set keys = new HashSet();
            for (Req req : reqs) {
                if (req.isDone){
                    req.success.accept(req.resBody);
                    keys.add(req);
                }
            }
            reqs.removeAll(keys);
//            Thread.sleep(3000);

        }
    }

    static class Req{
        String url="/path/";
        String method="post";
        String data="req_body_json";
        Boolean isDone=false;
        String resBody="";
        Consumer<String> success=(res)->{
            SomeTopic.debug(res.toUpperCase()+" "+this.hashCode());
        };
        Runnable a = ()->{
            System.out.println("aaaa");
        };
        Consumer<String> b = (cake)->{
            System.out.println("eat "+cake);
        };
        Callable<String> c = ()->{
            try {
                return "aaa";
            }catch (Exception e){
                return "bbb";
            }
        };
        Supplier<String> d = ()->{
            System.out.println("ddd");
            return "aaa";
        };
        Function<Integer,String> e = (x)->{
            System.out.println("x**3");
            return Math.pow(x,3)+"";
        };
        Predicate<String> f = x->x.startsWith("sss");

        Comparable<String> g = (x)->{
           return 11;
        };
        Comparator<String> h = (s1,s2) ->{
            return s1.indexOf("s");
        };


        @Override
        public String toString() {
            return "Req{" +
                    ", isDone=" + isDone +
                    ", resBody='" + this.hashCode() + '\'' +
                    '}';
        }
    }


}
